package com.hd.assistant.biz.manager.impl.ordermining;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.FutureTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.citrus.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.hd.assistant.biz.manager.AssistantManager;
import com.hd.assistant.biz.manager.exception.ManagerException;
import com.hd.assistant.biz.manager.ordermining.ItemCostCacheManager;
import com.hd.assistant.biz.manager.ordermining.OrderMiningManager;
import com.hd.assistant.biz.manager.ordermining.concurrent.ItemInsertDBTask;
import com.hd.assistant.dal.dao.exception.DAOException;
import com.hd.assistant.dal.dao.orderming.ITaskDAO;
import com.hd.assistant.dal.dao.orderming.ItemCostsDao;
import com.hd.assistant.dal.dao.orderming.NotifyMessageDAO;
import com.hd.assistant.dal.dao.orderming.TcOrderDAO;
import com.hd.assistant.dal.dao.query.ordermining.ItemCostQuery;
import com.hd.assistant.dal.dao.query.ordermining.TcOrderQuery;
import com.hd.assistant.dal.dataobject.User;
import com.hd.assistant.dal.dataobject.ordermining.ITask;
import com.hd.assistant.dal.dataobject.ordermining.ItemCost;
import com.hd.assistant.dal.dataobject.ordermining.NotifyMessage;
import com.hd.assistant.dal.dataobject.ordermining.Reports;
import com.hd.assistant.dal.dataobject.ordermining.SkuCost;
import com.hd.assistant.dal.dataobject.ordermining.TcOrder;
import com.hd.common.taobao.DefaultTaobaoISVAppManager;
import com.hd.util.CommonUtil;
import com.taobao.api.ApiException;
import com.taobao.api.domain.Item;
import com.taobao.api.domain.Order;
import com.taobao.api.domain.Sku;
import com.taobao.api.domain.Task;
import com.taobao.api.domain.Trade;
import com.taobao.api.request.TopatsResultGetRequest;
import com.taobao.api.request.TopatsTradesSoldGetRequest;
import com.taobao.api.request.TradeFullinfoGetRequest;
import com.taobao.api.request.TradesSoldGetRequest;
import com.taobao.api.request.TradesSoldIncrementGetRequest;
import com.taobao.api.response.TopatsResultGetResponse;
import com.taobao.api.response.TopatsTradesSoldGetResponse;
import com.taobao.api.response.TradeFullinfoGetResponse;
import com.taobao.api.response.TradesSoldGetResponse;
import com.taobao.api.response.TradesSoldIncrementGetResponse;

public class OrderMiningManagerImpl implements OrderMiningManager {

	private final static Logger log = LoggerFactory
			.getLogger(OrderMiningManagerImpl.class);
	@Autowired
	DefaultTaobaoISVAppManager taobaoISVAppManager;
	@Autowired
	AssistantManager assistantManager;
	@Autowired
	ItemCostsDao itemCostsDao;
	@Autowired
	ItemCostCacheManager itemCostCacheManager;

	@Autowired
	TcOrderDAO tcOrderDAO;
	@Autowired
	NotifyMessageDAO notifyMessageDAO;
	@Autowired
	ITaskDAO iTaskDAO;
	
	public TcOrderDAO getTcOrderDAO() {
		return tcOrderDAO;
	}

	public void setTcOrderDAO(TcOrderDAO tcOrderDAO) {
		this.tcOrderDAO = tcOrderDAO;
	}

	@Override
	public int dumpSellerItemsToDB(User u, String appkey, String secret,
			String sessionKey, Date startModify, Date endModify)
			throws ManagerException {
		if (u == null || secret == null || sessionKey == null) {
			throw new ManagerException(
					"error:uid==null || appkey == null || secret == null || sessionKey == null");
		}
		Date lastUpdate = endModify == null ? new Date() : endModify;
		try {
			List<Item> items = this.taobaoISVAppManager
					.getCurrentSellerAllOnSaleItems(appkey, secret, sessionKey,
							startModify, endModify);

			int count = checkItemsAndStore(u.getUserId(), items);
			if (updateUserLasetUpdatedTime(u.getId(), lastUpdate) > 0)
				u.setItemcostLastUpdate(lastUpdate);
			return count;
		} catch (ApiException e) {
			log.error("taobaoISVAppManager.getCurrentSellerAllOnSaleItems ", e);
			throw new ManagerException(
					"taobaoISVAppManager.getCurrentSellerAllOnSaleItems", e);
		}
	}

	@Override
	public int dumpSellerInventoryItemsToDB(User u, String appkey,
			String secret, String sessionKey, Date startModify, Date endModify)
			throws ManagerException {
		if (u == null || secret == null || sessionKey == null) {
			throw new ManagerException(
					"error:uid==null || appkey == null || secret == null || sessionKey == null");
		}
		try {
			List<Item> items = this.taobaoISVAppManager
					.getCurrentSellerInventoryItems(appkey, secret, sessionKey,
							startModify, endModify);

			int count = checkItemsAndStore(u.getUserId(), items);
			
			return count;
		} catch (ApiException e) {
			log.error("taobaoISVAppManager.getCurrentSellerAllOnSaleItems ", e);
			throw new ManagerException(
					"taobaoISVAppManager.getCurrentSellerAllOnSaleItems", e);
		}
	}
	
	private int checkItemsAndStore(Long userId, List<Item> items) {
		if (items == null || items.size() == 0)
			return 0;
		int count = 0;
		long start = System.currentTimeMillis();
		List<ItemCost> temp = new ArrayList<ItemCost>();

		for (Item item : items) {
			// 先从数据库中取
			try {
				ItemCost fromdb = this.itemCostsDao.getItemCostByItemId(item
						.getNumIid() + "");
				if (fromdb == null) {

					// insert
					ItemCost insert = new ItemCost();
					insert.setItemId(item.getNumIid() + "");
					insert.setItemPic(item.getPicUrl());
					insert.setPrice(CommonUtil.parseDouble(item.getPrice()));
					insert.setSjbm(item.getOuterId());
					insert.setTitle(item.getTitle());
					insert.setUserCats(item.getSellerCids());
					insert.setHasCost(0);
					insert.setHasSkuCosts(false);
					insert.setUserId(userId);
					insert.setNum(item.getNum());
					temp.add(insert);
				} else {
					boolean needUpdate = false;
					ItemCost update = new ItemCost();
					update.setItemId(fromdb.getItemId());
					if (fromdb.getTitle() != null
							&& !fromdb.getTitle().equals(item.getTitle())) {
						needUpdate = true;
						update.setTitle(item.getTitle());
					}
					if (fromdb.getSjbm() != null
							&& !fromdb.getSjbm().equals(item.getOuterId())) {
						needUpdate = true;
						update.setTitle(item.getTitle());
					}
					if (fromdb.getPrice() != null && item.getPrice() != null) {
						DecimalFormat df = new DecimalFormat("0.00");
						if (!item.getPrice().equals(
								df.format(fromdb.getPrice()))) {
							needUpdate = true;
							double p = CommonUtil.parseDouble(item.getPrice());
							update.setPrice(p);
						}
					}
					if (needUpdate) {
						count = count
								+ this.itemCostsDao.updateItemCost(update);
					}
				}

			} catch (DAOException e) {
				// TODO 异常处理
				log.error("error itemCostsDao:", e);
				continue;
			}
		}

		// 分情况处理插入
		if (temp.size() > 50) {
			// 超过一定数量 多线程处理
			int threadSize = 5;
			count = count + generateInsertTask(temp, threadSize);
		} else {
			// 直接单线程插入
			for (ItemCost insert : temp) {
				try {
					this.itemCostsDao.insertItemCost(insert);
				} catch (DAOException e) {
					// TODO 异常处理
					log.error("error itemCostsDao:", e);
					continue;
				}
				count++;
			}
		}

		long end = System.currentTimeMillis();
		System.out.println("checkItemsAndStore:" + (end - start));
		return count;

	}

	private int generateInsertTask(List<ItemCost> temp, int threadSize) {
		if (temp == null || temp.size() == 0)
			return 0;
		if (temp.size() < threadSize)
			threadSize = temp.size();

		int taskSize = (temp.size() % threadSize) == 0 ? temp.size()
				/ threadSize : (temp.size() / threadSize) + 1;

		CountDownLatch doneSignal = new CountDownLatch(threadSize);
		List<ItemCost> task = new ArrayList<ItemCost>();
		List<FutureTask<Integer>> futures = new ArrayList<FutureTask<Integer>>();
		for (int i = 0; i < threadSize; i++) {
			int begin = i * taskSize;
			int end = (i + 1) * taskSize > temp.size() ? temp.size() : (i + 1)
					* taskSize;
			task = new ArrayList<ItemCost>(temp.subList(begin, end));
			ItemInsertDBTask itemTask = new ItemInsertDBTask(task, doneSignal,
					this.itemCostsDao);
			FutureTask<Integer> f = new FutureTask<Integer>(itemTask);
			futures.add(f);
			new Thread(f).start();
		}

		try {
			doneSignal.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int total = 0;
		for (FutureTask<Integer> ff : futures) {
			try {
				total = total + ff.get();
			} catch (Exception e) {
				continue;
			}
		}
		return total;
	}

	private int updateUserLasetUpdatedTime(Long uid, Date lastUpdate)
			throws ManagerException {
		User user = new User();
		user.setItemcostLastUpdate(lastUpdate);
		user.setId(uid);
		return assistantManager.updateUser(user);
	}

	@Override
	public ItemCostQuery getItemsByQuery(ItemCostQuery query)
			throws ManagerException {

		try {
			return this.itemCostsDao.getItemCostsByQuery(query);
		} catch (DAOException e) {
			log.error("itemCostsDao.getItemCostsByQuery ", e);
			throw new ManagerException("itemCostsDao.getItemCostsByQuery ", e);
		}
	}

	@Override
	public int updateCost(String itemId, double cost) throws ManagerException {
		ItemCost update = new ItemCost();
		update.setItemId(itemId);
		update.setCost(cost);
		update.setHasCost(ItemCost.HAS_COST);
		update.setCostModifyTime(new Date());
		int u = 0;
		try {
			u = this.itemCostsDao.updateItemCost(update);
			return u;
		} catch (DAOException e) {
			log.error("itemCostsDao.updateItemCost ", e);
			throw new ManagerException("itemCostsDao.updateItemCost ", e);
		}

	}

	@Override
	public int batchUpdateCost(long userId, String[] itemIds, double ratio)
			throws ManagerException {
		if (ratio <= 0 || userId <= 0)
			return 0;
		ItemCostQuery query = new ItemCostQuery();
		query.setUserId(userId);
		query.setItemIds(itemIds);
		query.setCostRatio(ratio);
		;
		try {
			return this.itemCostsDao.batcjhUpdateCost(query);
		} catch (DAOException e) {
			log.error("itemCostsDao.batcjhUpdateCost ", e);
			throw new ManagerException("itemCostsDao.batcjhUpdateCost ", e);
		}
	}

	@Override
	public ItemCost loadAndStoreSkuInfo(String appkey, String secret,
			String sessionKey, String itemId) throws ManagerException {
		try {
			ItemCost fromDb = this.itemCostsDao.getItemCostByItemId(itemId);
			if (fromDb == null)
				return null;

			List<Sku> skus = this.taobaoISVAppManager.getSkuInfosByItemId(
					appkey, secret, sessionKey, itemId);
			for (Sku s : skus) {
				if (!fromDb.getSkuCost().containsKey(s.getSkuId() + "")) {
					String skuId = s.getSkuId() + "";
					String display = s.getPropertiesAlias();
					double price = CommonUtil.parseDouble(s.getPrice());
					double cost = fromDb.getCost() == null ? 0 : fromDb
							.getCost();
					SkuCost skuCost = new SkuCost(skuId, display, price, cost);
					fromDb.getSkuCost().put(skuId, skuCost);
				} else {
					SkuCost skuCost = fromDb.getSkuCost()
							.get(s.getSkuId() + "");
					double price = CommonUtil.parseDouble(s.getPrice());
					if (!skuCost.getPrice().equals(price)) {
						skuCost.setPrice(price);
						fromDb.getSkuCost().put(s.getSkuId() + "", skuCost);
					}
				}
			}
			fromDb.generateSkusFromMap();

			ItemCost update = new ItemCost();
			update.setItemId(itemId);
			update.setSkuCosts(fromDb.getSkuCosts());
			//update.setHasSkuCosts(true);
			if (this.itemCostsDao.updateItemCost(update) > 0) {
				update.setCost(fromDb.getCost());
				return update;
			}
		} catch (DAOException e) {
			log.error("itemCostsDao.getItemCostByItemId ", e);
			throw new ManagerException("itemCostsDao.getItemCostByItemId ", e);
		} catch (ApiException e) {
			log.error("ApiException getSkuInfosByItemId", e);
			throw new ManagerException("ApiException getSkuInfosByItemId ", e);
		}
		return null;
	}



	@Override
	public ItemCost getItemCostByItemId(String itemId) throws ManagerException {
		try {
			return this.itemCostsDao.getItemCostByItemId(itemId);
		} catch (DAOException e) {
			log.error("itemCostsDao.getItemCostByItemId ", e);
			throw new ManagerException("itemCostsDao.getItemCostByItemId ", e);
		}
	}

	@Override
	public int update(ItemCost update) throws ManagerException {
		try {
			return this.itemCostsDao.updateItemCost(update);
		} catch (DAOException e) {
			log.error("itemCostsDao.update ", e);
			throw new ManagerException("updateItemCost ", e);
		}
	}
	
	@Override
	public TcOrder getTcOrderByTid(Long tid) throws ManagerException {
		if(tid == null)
			return null;
		try {
			return this.tcOrderDAO.getTOrderByTid(tid);
		} catch (DAOException e) {
			log.error("tcOrderDAO.getTOrderByTid ", e);
			throw new ManagerException("getTcOrderByTid ", e);
		}
	}

	@Override
	public TcOrderQuery getTcOrdersByQuery(TcOrderQuery query)
			throws ManagerException {
		if(query == null || query.getUserId() == null)
			return null;
		try {
			return this.tcOrderDAO.getTOrdersByQuery(query);
		} catch (DAOException e) {
			log.error("tcOrderDAO.getTOrdersByQuery ", e);
			throw new ManagerException("getTcOrdersByQuery ", e);
		}
	}

	
	
	

	@Override
	public boolean calOrderProfit(TcOrder trade) throws ManagerException {
		if (trade == null || trade.getUserId() == null
				|| trade.getOrders() == null || trade.getOrders().size() == 0) {
			throw new ManagerException(
					"trade == null || trade.getOrders() == null || trade.getOrders().size() == 0");
		}
		double totalSales = 0;
		double totalProfit = 0;
		boolean isCalProfit = true;
		Set<String> includeItems = new HashSet<String>();
		Map<String, ItemCost> itemInfos = new HashMap<String, ItemCost>();

		// 获取卖家
		User user = itemCostCacheManager.getOrderMiningUser(trade.getUserId());
		int itemNums = 0;
		for (Order order : trade.getOrders()) {
			Long itemId = order.getNumIid();
			String itemIdStr = "" + itemId;
			Long num = order.getNum();
			String skuId = order.getSkuId();
			ItemCost cost = itemCostCacheManager.getItemCost(itemIdStr);
			includeItems.add(itemIdStr);
			if (cost == null || !cost.hasCostInfo()) {
				isCalProfit = false;
				// 无宝贝成本信息 退出计算
				// break;
			} else {
				double totalFee = CommonUtil.parseDouble(order.getTotalFee());
				totalSales += totalFee;
				double totalCost = generateItemCost(cost, num, skuId);// 获取宝贝总成本
																		// 如果有sku则获取sku成本
				double profit = (totalFee - totalCost);
				totalProfit += profit;

				ItemCost info = new ItemCost();
				info.setItemId(itemIdStr);
				info.setTotalSaleNum(num);
				info.setTotalSales(totalFee);
				info.setTotalProfits(profit);
				info.setNum(num);
				itemInfos.put(itemIdStr, info);
				//需要加上 如果付款时间小于 计算时间的话 则库存不减  防止初始化的时候减库存
				if(trade.getPayTime() == null)
					itemNums = itemNums+new Long(num).intValue();
				else{
					long payTime = trade.getPayTime().getTime();
					long current = System.currentTimeMillis();
					if(current - payTime <= 24*3600*1000){//付款时间在一周之内 算库存
						itemNums = itemNums+new Long(num).intValue();
					}
						
				}
				
				
				
				

			}
		}
		// 设置涉及宝贝
		trade.setIncludeItems(CommonUtil.join(includeItems.iterator(), ','));
		if (!isCalProfit) {
			// 表示没有库存信息 不计算
			trade.setIsProfitCal(TcOrder.PROFIT_CAL_NO_COST);
			trade.setProfitCalTime(new Date());
			return false;
		}

		// 计算信用卡成本
		if (!StringUtil.isBlank(trade.getCreditCardFee())
				&& user.getCreditCardRate() != null
				&& user.getCreditCardRate() > 0.00) {
			double cFee = CommonUtil.parseDouble(trade.getCreditCardFee());
			if (cFee > 0.00) {
				double creditCost = cFee * user.getCreditCardRate();
				trade.setCreditCardCost(creditCost);
				totalProfit -= creditCost;
			}
		}else{
			trade.setCreditCardCost(0.00);
		}
		// 计算商城成本
		if (user.getType().equals("B") && user.getTmallRate() != null
				&& user.getTmallRate() > 0.00) {
			double pay = CommonUtil.parseDouble(trade.getPayment());// 应付金额
																	// 含邮费计算
			pay = pay - CommonUtil.parseDouble(trade.getPostFee());
			double tmallCost = pay * user.getTmallRate();
			trade.setTmallCost(tmallCost);
			totalProfit -= tmallCost;
		}else{
			trade.setTmallCost(0.00);
		}

		// 更新宝贝表的 总 销售额 销量 成本
		generateItemCostInfo(itemInfos);

		trade.setSales(totalSales);
		trade.setProfit(totalProfit);
		trade.setIsProfitCal(TcOrder.PROFIT_CAL_SUCCESS);
		trade.setProfitCalTime(new Date());
		trade.setItemNums(itemNums);
		// 获取到订单涉及到的宝贝以及数目
		return true;
	}

	private void generateItemCostInfo(Map<String, ItemCost> itemInfos) {
		for (Map.Entry<String, ItemCost> entry : itemInfos.entrySet()) {
			String itemId = entry.getKey();
			ItemCost update = entry.getValue();
			update.setItemId(itemId);
			try {
				this.itemCostsDao.autoUpdateItemCostSaleInfo(update);
			} catch (DAOException e) {
				log.error("generateItemCostInfo itemId=" + itemId, e);
			}
		}
	}

	private double generateItemCost(ItemCost cost, Long num, String skuId) {
		double single = 0;
		if (cost.hasSkuCosts()) {
			single = cost.getSkuCost().get(skuId).getCost();
		} else {
			single = cost.getCost();
		}
		return single * num;
	}

	private List<String> getNeedToCalProfitStatus(){
		List<String> list = new ArrayList<String>();
		list.add("WAIT_SELLER_SEND_GOODS");
		list.add("WAIT_BUYER_CONFIRM_GOODS");
		list.add("TRADE_BUYER_SIGNED");
		list.add("TRADE_FINISHED");
		return list;
	}
	private boolean needCalProfit(String status) {
		List<String> list = getNeedToCalProfitStatus();
		return list.contains(status);
	}

	/**
	 * 根据条件更新交易信息 只有在当前交易信息的状态优先于db中的时候才更新
	 * 
	 * @param fromDb
	 * @param t
	 * @throws DAOException
	 * @throws ManagerException
	 */
	private void updateTrade(TcOrder fromDb, Trade t ) throws DAOException,
			ManagerException {
		int local = getTradeStatus(fromDb.getStatus());
		int remote = getTradeStatus(t.getStatus());
		if (local >= remote) {
			return;
		} else {
			// 表示需要更新
			TcOrder update = null;
			if (fromDb.hasCalProfitSuccess() || !needCalProfit(t.getStatus())) {
				update = new TcOrder();
				update.setModified(t.getModified());
				update.setPayTime(t.getPayTime());
				update.setEndTime(t.getEndTime());
				update.setStatus(t.getStatus());
				update.setTid(fromDb.getTid());
				if(t.getPayment() != null){
					update.setPayment(t.getPayment());
				}
				if(t.getPostFee() != null){
					update.setPostFee(t.getPostFee());
				}
				update.setOrdersJson(JSONObject.toJSONString(t.getOrders()),
						false);
			} else {
				fromDb.setPayTime(t.getPayTime());
				fromDb.setEndTime(t.getEndTime());
				update = calOrderProfitAndReturnUpdate(fromDb);
				if(update == null)
					return;
				update.setModified(t.getModified());
				update.setStatus(t.getStatus());
				update.setOrdersJson(JSONObject.toJSONString(t.getOrders()),
						false);
				update.setTid(fromDb.getTid());
				update.setPayTime(t.getPayTime());
				update.setEndTime(t.getEndTime());
				if(t.getPayment() != null){
					update.setPayment(t.getPayment());
				}
				if(t.getPostFee() != null){
					update.setPostFee(t.getPostFee());
				}
			}
			this.tcOrderDAO.updateTOrder(update);
		}

	}

	private int getTradeStatus(String status) {
		if (status == null)
			return 0;
		if (status.equals("TRADE_NO_CREATE_PAY"))
			return 1;
		if (status.equals("WAIT_BUYER_PAY"))
			return 2;
		if (status.equals("WAIT_SELLER_SEND_GOODS"))
			return 4;
		if (status.equals("SELLER_CONSIGNED_PART"))
			return 8;
		if (status.equals("WAIT_BUYER_CONFIRM_GOODS"))
			return 16;
		if (status.equals("TRADE_BUYER_SIGNED"))
			return 32;
		if (status.equals("TRADE_FINISHED"))
			return 64;
		if (status.equals("RADE_CLOSED"))
			return 128;
		if (status.equals("TRADE_CLOSED_BY_TAOBAO"))
			return 128;
		return 0;
	}

	@Override
	public TcOrder calOrderProfitAndReturnUpdate(TcOrder trade)
			throws ManagerException {
		if (calOrderProfit(trade)) {
			TcOrder update = new TcOrder();
			update.setIncludeItems(trade.getIncludeItems());
			update.setSales(trade.getSales());
			update.setProfit(trade.getProfit());
			update.setIsProfitCal(trade.getIsProfitCal());
			update.setProfitCalTime(trade.getProfitCalTime());
			update.setTmallCost(trade.getTmallCost());
			update.setCreditCardCost(trade.getCreditCardCost());
			update.setItemNums(trade.getItemNums());
			return update;
		}else{
			TcOrder update = new TcOrder();
			update.setIsProfitCal(TcOrder.PROFIT_CAL_NO_COST);
			update.setProfitCalTime(trade.getProfitCalTime());
			return update;
		}
	}

	@Override
	public Trade getOrderAppTradeInfoByTid(Long tid,Long userId) throws ManagerException {
		User user = itemCostCacheManager.getOrderMiningUser(userId);
		if(user == null){
			return null;
		}
		TradeFullinfoGetRequest req = new TradeFullinfoGetRequest();
		req.setTid(tid);
		try {
			TradeFullinfoGetResponse response = this.taobaoISVAppManager.getTradeByTid(this.taobaoISVAppManager.getOrderAppKey(), this.taobaoISVAppManager.getOrderAppSecret(), user.getToken(), req);
			return response.getTrade();
		} catch (ApiException e) {
			log.error("api error : taobaoISVAppManager.getTradeByTid tid="+tid);
			throw new ManagerException("error : getTradeByTid tid="+tid, e);
		}
	}
	
	@Override
	public int defaultDumpTradesToDB(User user, String appkey, String secret,
			String sessionKey, Long limit) throws ManagerException {
		if (limit == null || limit == 0)
			limit = 100l;
		long pageSize = 100l;
		long pageTotal = limit/pageSize;
		if(limit % pageSize != 0)
			pageTotal = pageTotal +1;
		Date endCreate = new Date();
		long page = 1l;
		long start = System.currentTimeMillis();
		TradesSoldGetRequest reqs = new TradesSoldGetRequest();
		reqs.setPageSize(pageSize);
		reqs.setEndCreated(endCreate);
		reqs.setUseHasNext(true);
		reqs.setPageNo(page);
		TradesSoldGetResponse r;
		try {
			int count = 0;
			
			do{
				r = this.taobaoISVAppManager.getTradesByCreateTime(appkey, secret,
						sessionKey, reqs);
				List<Trade> trades = r.getTrades();
				if(trades == null)
					continue;;
				
				for (Trade t : trades) {
					convertTrade(t, user.getUserId());
					count++;
				}
				page ++;
				if(page > pageTotal)
					break;
				reqs.setPageNo(page);
			}while(r.getHasNext());
			
			
			long end = System.currentTimeMillis();
			System.out.println("defaultDumpTradesToDB:"+(end - start));
			return count;
		} catch (ApiException e) {
			log.error("api error : taobaoISVAppManager.getTradesByCreateTime");
			throw new ManagerException("error : defaultDumpTradesToDB", e);
		}

	}


	@Override
	public int dumpTodayTradesToDB(User user, String appkey, String secret,
			String sessionKey) throws ManagerException {
		Calendar cal = Calendar.getInstance();
		long end = System.currentTimeMillis();
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		int minute = cal.get(Calendar.MINUTE);
		int second = cal.get(Calendar.SECOND);
		int mil = cal.get(Calendar.MILLISECOND);
		long begin = end - hour*3600*1000 - minute*60*1000 - second*1000 - mil;
		
		Date todayBegin = new Date(begin);
		Date todayEnd = new Date(end);
		long page = 1l;
		long pageSize = 40l;
		
		TradesSoldIncrementGetRequest req= new TradesSoldIncrementGetRequest();
		req.setUseHasNext(true);
		req.setPageNo(page);
		req.setPageSize(pageSize);
		req.setStartModified(todayBegin);
		req.setEndModified(todayEnd);
		TradesSoldIncrementGetResponse r = null;
		int count = 0;
		do{
			try {
				r = this.taobaoISVAppManager.getIncrementTrades(appkey, secret, sessionKey, req);
				List<Trade> trades = r.getTrades();
				if(trades == null)
					continue;;
				
				for (Trade t : trades) {
					convertTrade(t, user.getUserId());
					count++;
				}
				page ++;
			
				req.setPageNo(page);
			} catch (ApiException e) {
				log.error("api error : taobaoISVAppManager.getIncrementTrades");
				throw new ManagerException("error : dumpTodayTradesToDB", e);
			}
		}while(r!=null && r.getHasNext());
		
		
		return count;
	}


	@Override
	public int dumpNearlyTradesToDB(User user, String appkey, String secret,
			String sessionKey) throws ManagerException {
		//异步加载前90天订单
		TopatsTradesSoldGetRequest req = new TopatsTradesSoldGetRequest();
		Calendar cal = Calendar.getInstance();
		long end = System.currentTimeMillis();
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		int minute = cal.get(Calendar.MINUTE);
		int second = cal.get(Calendar.SECOND);
		int mil = cal.get(Calendar.MILLISECOND);
		long endTime = end - hour*3600*1000l - minute*60*1000l - second*1000l - mil;
		long r = 90*24*3600*1000l;
		long startTime = endTime-r;
		
		endTime = endTime - 12*3600*1000l;
		Date to = new Date(endTime);
		Date from = new Date(startTime);
		req.setStartTime(new SimpleDateFormat("yyyyMMdd").format(from));
		req.setEndTime(new SimpleDateFormat("yyyyMMdd").format(to));
		
		try {
			TopatsTradesSoldGetResponse response = this.taobaoISVAppManager.getTrades(appkey, secret, sessionKey, req);
			if(response != null && response.getTask() != null){
				ITask task = new ITask(response.getTask());
				task.setUserId(user.getUserId());
				task.setType(ITask.TYPE_TRADEGET);
				this.iTaskDAO.insertTask(task);
				
				log.warn("Task sumbmit ok . taskid="+response.getTask());
				return 1;
			}
		} catch (ApiException e) {
			log.error("api error : taobaoISVAppManager.getTrades",e);
			throw new ManagerException("error : dumpNearlyTradesToDB", e);
		} catch (DAOException e) {
			log.error("DAOException : iTaskDAO.insertTask",e);
			throw new ManagerException("error : dumpNearlyTradesToDB", e);
		}
		return 0;
	}
	
	public void convertTrade(Trade t, Long userId) {
		try {
			// 先去数据库中找 没有才插入 有的话 走是否需要更新逻辑
			TcOrder trade = this.tcOrderDAO.getTOrderByTid(t.getTid());
			convertTrade(t, trade, userId);
		} catch (DAOException e) {
			log.error("DAOException error convertTrade:this.tcOrderDAO.insertTOrder");
		} 
	}
	
	public void convertTrade(Trade t,TcOrder trade, Long userId) {
		if(t == null)
			return;
		try {
			if (trade == null) {
				TcOrder insert = new TcOrder(t);
				insert.setIsProfitCal(TcOrder.PROFIT_CAL_INIT);
				insert.setOrdersJson(JSONObject.toJSONString(t.getOrders()),
						false);
				insert.setUserId(userId);
				if (needCalProfit(insert.getStatus()))
					calOrderProfit(insert);	
				this.tcOrderDAO.insertTOrder(insert);
			} else {
				updateTrade(trade, t);
			}

		} catch (DAOException e) {
			log.error("DAOException error convertTrade:this.tcOrderDAO.insertTOrder");
		} catch (ManagerException e) {
			log.error("ManagerException error convertTrade:calOrderProfit");
		}
	}

	@Override
	public int calProfitOfAllDbNoprofitTcOrders(User user,Date endTimeStart) {
		long start = System.currentTimeMillis();
		int count = 0;
		int pageSize = 100;
		TcOrderQuery query = new TcOrderQuery();
		query.setUserId(user.getUserId());
		query.setPageSize(pageSize);
		query.setPage(1);
		query.setStatuses(this.getNeedToCalProfitStatus());
		if(endTimeStart != null)
			query.setEndTimeStart(endTimeStart);
		List<Integer> calStatus = new ArrayList<Integer>();
		calStatus.add(TcOrder.PROFIT_CAL_INIT);
		calStatus.add(TcOrder.PROFIT_CAL_NO_COST);
		query.setProfitCalStatus(calStatus);
		while (query.hasNext()){
			try {
				query = this.tcOrderDAO.getTOrdersByQuery(query);
				if(query.getTcOrders() == null)
					break;
				TcOrder update;
				for(TcOrder tcOrder : query.getTcOrders()){
					try {
						update = calOrderProfitAndReturnUpdate(tcOrder);
						if(update == null)
							continue;
						update.setTid(tcOrder.getTid());
						count = count + this.tcOrderDAO.updateTOrder(update);
					} catch (ManagerException e) {
						log.error("calOrderProfitAndReturnUpdate error",e);
						continue;
					}

				}
				query.setPage(query.nextPage());
				query.setTcOrders(null);
			} catch (DAOException e) {
				log.error("DAOException error this.tcOrderDAO.getTOrdersByQuery(query)",e);
				break;
			}
		}
		long end = System.currentTimeMillis();
		System.out.println("calProfitOfAllDbNoprofitTcOrders:"+(end -start));
		return count;
	}

	@Override
	public void insertNotifyMessage(NotifyMessage message)
			throws ManagerException {
		try {
			notifyMessageDAO.insertNotifyMessage(message);
		} catch (DAOException e) {
			log.error("insertNotifyMessage error",e);
			throw new ManagerException("insertNotifyMessage error:",e);
		}
	}

	@Override
	public Task getTaskInfoByTaskId(Long taskId) throws ManagerException{
		TopatsResultGetRequest req = new TopatsResultGetRequest();
		req.setTaskId(taskId);
		try {
			TopatsResultGetResponse response = this.taobaoISVAppManager.getTopatsByTaskid(this.taobaoISVAppManager.getOrderAppKey(), 
					this.taobaoISVAppManager.getOrderAppSecret(), req);
			if(response != null)
				return response.getTask();
			else
				return null;
		} catch (ApiException e) {
			log.error("getTaskInfoByTaskId error",e);
			throw new ManagerException("getTaskInfoByTaskId error:taskid= "+taskId,e);
		}
	}

	@Override
	public int update(TcOrder order) throws ManagerException {
		if(order ==null || order.getTid() == null)
			return 0;
		try {
			return this.tcOrderDAO.updateTOrder(order);
		} catch (DAOException e) {
			log.error("getTaskInfoByTaskId error",e);
			throw new ManagerException("updateTOrder error:tid= "+order.getTid(),e);
		}
	}

	@Override
	public boolean reCalProfit(Long tid) throws ManagerException {
		try {
			TcOrder fromdb = this.tcOrderDAO.getTOrderByTid(tid);
			if(fromdb != null && needCalProfit(fromdb.getStatus())){
				TcOrder update = this.calOrderProfitAndReturnUpdate(fromdb);
				tcOrderDAO.updateTOrder(update);
			}
		} catch (DAOException e) {
			log.error("reCalProfit tid="+tid,e);
			return false;
		}
		return false;
	}

	@Override
	public List<Reports> getReportsByUserId(Long userId,Integer type, String dateFrom,
			String dateTo) throws ManagerException {
		try {
			return this.tcOrderDAO.getReportsByUserId(userId, type, dateFrom, dateTo);
		} catch (DAOException e) {
			log.error("getReportsByUserId error userId="+userId,e);
			throw new ManagerException("getReportsByUserId error userId="+userId,e);
		}
	}

	@Override
	public List<Reports> getBuyerReportsByUserId(Long userId, Integer tradeFrom)
			throws ManagerException {
		try {
			return this.tcOrderDAO.getBuyerReportsByUserId(userId, tradeFrom);
		} catch (DAOException e) {
			log.error("getReportsByUserId error userId="+userId,e);
			throw new ManagerException("getBuyerReportsByUserId error userId="+userId,e);
		}
	}

	

	
	



	

	


}
